﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SIA.HwAccess.PLCSiemens.ConnectionDriver
{
    static internal class S7Metods
    {
        //Risposta ad una richiesta FETCH
        private static readonly Byte[] fetchResponse = new Byte[] 
                                                            { 83    //S
                                                            , 53    //5
                                                            , 16    //16 byte
                                                            , 1, 3
                                                            , 6     //FETCH
                                                            , 15, 3
                                                            , 0     //Nessun Errore
                                                            , 255, 7 };
        //Risposta ad una richiesta WRITE
        private static readonly Byte[] writeResponse = new Byte[]
                                                            { 83    //S
                                                            , 53    //5
                                                            , 16    //16 byte
                                                            , 1, 3
                                                            , 4     //WRITE
                                                            , 15, 3
                                                            , 0     //Nessun Errore
                                                            , 255, 7 };


        /// <summary>Risposta ad una richiesta FETCH</summary>
        public static Byte[] FetchResponse { get { return fetchResponse; } }
        /// <summary>Risposta ad una richiesta WRITE</summary>
        public static Byte[] WriteResponse { get { return writeResponse; } }


        /// <summary>Intestazione Messaggio S5 (16 byte) per la lettura</summary>
        /// <param name="nDB"></param>
        /// <param name="_startByte"></param>
        /// <param name="nWord"></param>
        /// <returns></returns>
        public static byte[] GetHeaderRead(byte nDB, int startByte, int nWord)
        {
            byte[] buffByte = new byte[16];

            buffByte[0] = 83;   //S
            buffByte[1] = 53;   //5
            buffByte[2] = 16;   //Len Header 16 byte
            buffByte[3] = 1;
            buffByte[4] = 3;
            buffByte[5] = 5;
            buffByte[6] = 3;
            buffByte[7] = 8;
            buffByte[8] = 1;    //1=DataBlock,2=M, 3=E, 4=A, 5=PEW/PAW, 6=Z, 7=T
            buffByte[9] = nDB;
            buffByte[10] = Convert.ToByte(startByte / 256);
            buffByte[11] = Convert.ToByte(startByte % 256);
            buffByte[12] = Convert.ToByte(nWord / 256);
            buffByte[13] = Convert.ToByte(nWord % 256);
            buffByte[14] = 255;
            buffByte[15] = 2;

            return buffByte;
        }

        //eAreaType
        public static byte[] GetHeaderRead(IHwAddress address)
        {
            byte[] buffByte = new byte[16];

            buffByte[0] = 83;   //S
            buffByte[1] = 53;   //5
            buffByte[2] = 16;   //Len Header 16 byte
            buffByte[3] = 1;
            buffByte[4] = 3;
            buffByte[5] = 5;
            buffByte[6] = 3;
            buffByte[7] = 8;
            buffByte[8] = 1;    //1=DataBlock,2=M, 3=E, 4=A, 5=PEW/PAW, 6=Z, 7=T
            buffByte[9] = Convert.ToByte(address.DataBlock);
            buffByte[10] = Convert.ToByte(address.StartByte / 256);
            buffByte[11] = Convert.ToByte(address.StartByte % 256);
            buffByte[12] = Convert.ToByte((int)(address.LenByte/2) / 256);
            buffByte[13] = Convert.ToByte((int)(address.LenByte/2) % 256);
            buffByte[14] = 255;
            buffByte[15] = 2;

            return buffByte;
        }
        private static byte eAreaType2HeaderByte(eAreaType areaType)
        {
            switch (areaType)
            {
                case eAreaType.NONE:
                    throw new Exception("Indirizzo non Supportato");
                case eAreaType.DB:
                    return 1;
                case eAreaType.M:
                    return 2;
                case eAreaType.E:
                    return 3;
                case eAreaType.A:
                    return 4;
                case eAreaType.T:
                    return 7;
                case eAreaType.Z:
                    return 6;
                case eAreaType.PA:
                    return 5;
                case eAreaType.PE:
                    return 5;
                case eAreaType.RAW_READ:
                    throw new Exception("Indirizzo non Supportato");
                case eAreaType.RAW_WRITE:
                    throw new Exception("Indirizzo non Supportato");
                default:
                    throw new Exception("Indirizzo non Supportato");
            }
        
        }

        /// <summary>Creazione Messaggio S5(16 byte) per la scrittura</summary>
        /// <param name="nDB"></param>
        /// <param name="_startByte"></param>
        /// <param name="nWord"></param>
        /// <returns></returns>
        public static byte[] GetHeaderWrite(byte nDB, int startByte, int nWord)
        {
            //Creazione messaggio S5 (16 byte)

            byte[] buffByte = new byte[16];

            buffByte[0] = 83; //S
            buffByte[1] = 53; //5
            buffByte[2] = 16;
            buffByte[3] = 1;
            buffByte[4] = 3;
            buffByte[5] = 3;
            buffByte[6] = 3;
            buffByte[7] = 8;
            buffByte[8] = 1;    //1=DataBlock,2=M, 3=E, 4=A, 5=PEW/PAW, 6=Z, 7=T
            buffByte[9] = nDB;
            buffByte[10] = Convert.ToByte(startByte / 256);
            buffByte[11] = Convert.ToByte(startByte % 256);
            buffByte[12] = Convert.ToByte(nWord / 256);
            buffByte[13] = Convert.ToByte(nWord % 256);
            buffByte[14] = 255;
            buffByte[15] = 2;

            return buffByte;
        }
    }
}
